﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Windows.Threading;
using System.Windows.Media.Animation;

namespace ToolTipTest
{
    /// <summary>
    /// Interaction logic for Tooltip.xaml
    /// </summary>
    public partial class CustomTooltip : UserControl
    {
        public bool hasAnimation = true;
        public double maxOpacity = 0.95;
        DispatcherTimer timer = new DispatcherTimer();
        public CustomTooltip()
        {
            InitializeComponent();
            FlowDocument myFlowDoc = new FlowDocument();

            // Add paragraphs to the FlowDocument.
            myFlowDoc.Blocks.Add(new Paragraph(new Run("Paragraph 1")));
            myFlowDoc.Blocks.Add(new Paragraph(new Run("Paragraph 2")));
            myFlowDoc.Blocks.Add(new Paragraph(new Run("Paragraph 3")));

            // Add initial content to the RichTextBox.
            TextBlockToolTip.Document = myFlowDoc;
            
        }
        protected override void OnPropertyChanged(DependencyPropertyChangedEventArgs e)
        {
            if (e.Property == isCloseableProperty) {
                if (!isCloseable)
                {
                    CloseButton.Visibility = Visibility.Collapsed;
                }
                else {
                    CloseButton.Visibility = Visibility.Visible;
                }
            }
            base.OnPropertyChanged(e);
        }


        public double UserControlToolTipX
        {
            get { return this.UserControlToolTipXY.X; }
            set { this.UserControlToolTipXY.X = value; }
        }

        public double UserControlToolTipY
        {
            get { return this.UserControlToolTipXY.Y; }
            set { this.UserControlToolTipXY.Y = value; }
        }

        private double animationDuration =1;
        public double AnimationDuration
        {
            get { return this.animationDuration; }
            set { this.animationDuration = value; }
        }

        public RichTextBox UserControlTextBlockToolTip
        {
            get { return TextBlockToolTip; }
        }

        public string UserControlToolTipTitle
        {
            get { return ToolTipTitle.Text; }
            set { ToolTipTitle.Text = value; }
        }

        public void show(int milis)
        {
            if (!timer.IsEnabled)
            {
                if (hasAnimation)
                {                   
                    ChangeVisibilityWithAnimation(true);
                }
                else
                {
                    this.Opacity = maxOpacity;
                    this.Visibility = Visibility.Visible;
                }
                goToSleep(milis);
            }
            else { }
        }
        public void stop()
        {
            if (!hasAnimation)
            {
                this.Visibility = Visibility.Collapsed;
            }
            else
            {
                ChangeVisibilityWithAnimation(false);
            }
            timer.Stop();
        }
        private void goToSleep(int milis)
        {
            if (this.Visibility == Visibility.Visible || timer.IsEnabled)
            {
                timer.Stop();
            }
            timer.Tick += new EventHandler(delegate(object s, EventArgs a)
            {
                if (!DragControl.isMouseDown)
                {
                    stop();
                }
            });
            timer.Interval = new TimeSpan(0, 0, 0, milis / 1000, milis % 1000);
            timer.Start();
        }
        private void Button_Click(object sender, RoutedEventArgs e)
        {
            stop();
        }
        private bool isAnimCollapsedInUse = false;
        public void ChangeVisibilityWithAnimation(bool collapse)
        {
            
            if (!isAnimCollapsedInUse)
            {                
                string controlName = "control1";
                UserControl temp = this;
                this.RegisterName(controlName, temp);

                Duration duration = new Duration(TimeSpan.FromSeconds(animationDuration));
                Storyboard story = new Storyboard();

                DoubleAnimation animCollapsed = new DoubleAnimation();                
                
                DoubleAnimation animScaleX = new DoubleAnimation();
                animScaleX.Duration = duration;
                animScaleX.AccelerationRatio = 0.1;
                animScaleX.DecelerationRatio = 0.1;
                Storyboard.SetTargetProperty(animScaleX, new PropertyPath(CustomTooltip.ScaleXProperty));
                Storyboard.SetTargetName(animScaleX, controlName);
                
                DoubleAnimation animScaleY = new DoubleAnimation();
                animScaleY.Duration = duration;
                animScaleY.AccelerationRatio = 0.1;
                animScaleY.DecelerationRatio = 0.1;
                Storyboard.SetTargetProperty(animScaleY, new PropertyPath(CustomTooltip.ScaleYProperty));
                Storyboard.SetTargetName(animScaleY, controlName);
                                
                if (!collapse)
                {
                    animCollapsed.To = 0;
                    
                    animScaleY.From = 1;
                    animScaleY.To = 0;
                    animScaleX.From = 1;
                    animScaleX.To = 0;
                }
                else
                {
                    animScaleY.From = 0;
                    animScaleY.To = 1;
                    animScaleX.From = 0;
                    animScaleX.To = 1;

                    animCollapsed.To = maxOpacity;
                    this.Visibility = Visibility.Visible;
                }

                story.Children.Add(animScaleX);
                story.Children.Add(animScaleY);
                animCollapsed.Duration = duration;
                animCollapsed.AccelerationRatio = 0.1;
                animCollapsed.DecelerationRatio = 0.1;
                Storyboard.SetTargetProperty(animCollapsed, new PropertyPath(UserControl.OpacityProperty));
                Storyboard.SetTargetName(animCollapsed, controlName);
                story.Children.Add(animCollapsed);

                animCollapsed.Completed += delegate
                {
                    isAnimCollapsedInUse = false;
                    if (this.Opacity < 0.01)
                    {
                        this.Visibility = Visibility.Collapsed;
                    }
                };

                isAnimCollapsedInUse = true;
                story.Begin(this);
            }
        }
        #region Dependency Properties

        public static DependencyProperty isCloseableProperty = DependencyProperty.RegisterAttached("isCloseable", typeof(bool), typeof(CustomTooltip), new PropertyMetadata(true));
        public bool isCloseable
        {
            get { return (bool)GetValue(isCloseableProperty); }
            set
            {
                SetValue(isCloseableProperty, value);
            }
        }

        public static DependencyProperty ScaleXProperty = DependencyProperty.RegisterAttached("ScaleX", typeof(double), typeof(CustomTooltip), new PropertyMetadata(0.0));
        public double ScaleX
        {
            get { return (double)GetValue(ScaleXProperty); }
            set
            {
                SetValue(ScaleXProperty, value);
            }
        }
        public static DependencyProperty ScaleYProperty = DependencyProperty.RegisterAttached("ScaleY", typeof(double), typeof(CustomTooltip), new PropertyMetadata(0.0));
        public double ScaleY
        {
            get { return (double)GetValue(ScaleYProperty); }
            set
            {
                SetValue(ScaleYProperty, value);
            }
        }

        #endregion

    }
}
